#include "stdafx.h"
#include "CompositionStringClass.h"


BOOL CompositionStringClass::isInit = FALSE;

CompositionStringClass::CompositionStringClass(LPCOMPOSITIONSTRING lpCompStr)
{
	this->lpCompStr = lpCompStr;
}

VOID CompositionStringClass::SetCompositionString(CONST std::wstring& str)
{
	LPMYCOMPSTR lpMyCompStr = (LPMYCOMPSTR)this->lpCompStr;
	_tcscpy(lpMyCompStr->szCompStr,str.c_str());
	this->lpCompStr->dwCompStrLen = str.size();
}
VOID CompositionStringClass::SetResultString(CONST std::wstring& str)
{
	LPMYCOMPSTR lpMyCompStr = (LPMYCOMPSTR)this->lpCompStr;
	_tcscpy(lpMyCompStr->szResultStr,str.c_str());
	this->lpCompStr->dwResultStrLen =str.size();
}
VOID CompositionStringClass::ClearCompStr()
{
	LPMYCOMPSTR lpMyCompStr = (LPMYCOMPSTR)this->lpCompStr;
	lpMyCompStr->inputLen = 0;
	this->SetCompositionString(_T("\0"));
}

VOID CompositionStringClass::Initial()
{
	this->lpCompStr->dwSize = sizeof(MYCOMPSTR);
	lpCompStr->dwCursorPos = 0;
	this->lpCompStr->dwCompStrOffset = (DWORD)((LPMYCOMPSTR)(this->lpCompStr))->szCompStr - (DWORD)this->lpCompStr;
	this->lpCompStr->dwResultStrOffset = (DWORD)((LPMYCOMPSTR)(this->lpCompStr))->szResultStr - (DWORD)this->lpCompStr;
	this->ClearCompStr();
	this->SetResultString(_T("\0"));
}

UINT CompositionStringClass::GetInputLen() CONST
{
	return ((LPMYCOMPSTR)(this->lpCompStr))->inputLen;
}

BOOL CompositionStringClass::PutCode(CONST std::wstring& str)
{
	LPMYCOMPSTR lpMyComp = (LPMYCOMPSTR)this->lpCompStr;
	if(lpMyComp->inputLen >= MAX_INPUT)
		return FALSE;
	LPUSRINPUT lpPtr = &(lpMyComp->input[lpMyComp->inputLen ++]);
	lpPtr->op_STROKE = FALSE;
	lpPtr->op_YIN = FALSE;
	_tcscpy(lpPtr->baseCode,str.c_str());
	this->_toCompStr();
	return TRUE;
}
BOOL CompositionStringClass::PutStroke(BYTE biHua)
{
	LPUSRINPUT lpPtr;
	LPMYCOMPSTR lpMyComp = (LPMYCOMPSTR)this->lpCompStr;
	if(lpMyComp->inputLen >= MAX_INPUT)
		return FALSE;
	if(lpMyComp->inputLen > 0)
	{
		lpPtr =  &(lpMyComp->input[lpMyComp->inputLen - 1]);
		if(lpPtr->op_STROKE)
		{
			if(lpPtr->STROKE != biHua)
			{
				lpPtr->STROKE = biHua;
				return TRUE;
			}
			else
				return FALSE;
		}
		else if(lpPtr->op_YIN)
		{
			--lpPtr;
			if(lpPtr->op_STROKE)
			{
				if(lpPtr->STROKE != biHua)
				{
					lpPtr->STROKE = biHua;
					return TRUE;
				}
				else
					return FALSE;
			}
		}
		else
		{
			lpPtr = &(lpMyComp->input[lpMyComp->inputLen++]);
			lpPtr->op_STROKE = TRUE;
			lpPtr->STROKE = biHua;
			lpPtr->op_YIN = FALSE;
			lpPtr->baseCode[0] = '\0';
			return TRUE;
		}
	}
	return FALSE;
}
BOOL CompositionStringClass::PutPY(TCHAR pinyin)
{
	LPUSRINPUT lpPtr;
	pinyin = tolower(pinyin);
	LPMYCOMPSTR lpMyComp = (LPMYCOMPSTR)this->lpCompStr;
	if(lpMyComp->inputLen >= MAX_INPUT)
		return FALSE;
	if(lpMyComp->inputLen > 0)
	{
		lpPtr =  &(lpMyComp->input[lpMyComp->inputLen - 1]);
		if(lpPtr->op_YIN)
		{
			if(lpPtr->op_YIN != pinyin)
			{
				lpPtr->YIN = pinyin;
				return TRUE;
			}
			else
				return FALSE;
		}
		else if(lpPtr->STROKE)
		{
			--lpPtr;
			if(lpPtr->op_YIN)
			{
				if(lpPtr->YIN != pinyin)
				{
					lpPtr->YIN = pinyin;
					return TRUE;
				}
				else
					return FALSE;
			}
		}
		else
		{
			lpPtr = &(lpMyComp->input[lpMyComp->inputLen++]);
			lpPtr->op_STROKE = FALSE;
			lpPtr->YIN = pinyin;
			lpPtr->op_YIN = TRUE;
			lpPtr->baseCode[0] = '\0';
			return TRUE;
		}
	}
	return FALSE;
}
BOOL CompositionStringClass::UndoInput()
{
	LPMYCOMPSTR lpMyComp = (LPMYCOMPSTR)lpCompStr;
	if(lpMyComp->inputLen > 0)
	{	
		lpMyComp->inputLen--;
		if(lpMyComp->inputLen > 0)
		{
			this->_toCompStr();
		}
		else
		{
			this->ClearCompStr();
		}
	}
	return TRUE;
}
VOID CompositionStringClass::_toCompStr()
{
	LPMYCOMPSTR lpMyComp = (LPMYCOMPSTR)this->lpCompStr;
	TCHAR compstr[MAX_INPUT * BASE_CODE_LEN] = {'\0'};
	for(int i = 0;i < lpMyComp->inputLen; ++i)
	{
		LPUSRINPUT lpUsrIpt = &(compstr,lpMyComp->input[i]);
		if(lpUsrIpt->op_STROKE || lpUsrIpt->op_YIN)
			continue;
		_tcscat(compstr,lpUsrIpt->baseCode);		
		if(lpMyComp->inputLen - 1 != i)
			_tcscat(compstr,_T(","));
	}
	_tcscpy(lpMyComp->szCompStr,compstr);
	lpCompStr->dwCompStrLen = _tcslen(compstr);
}

VOID CompositionStringClass::OutputCompString()
{
	this->_toCompStr();
	this->SetResultString(((LPMYCOMPSTR)this->lpCompStr)->szCompStr);
}
CONST LPTSTR CompositionStringClass::GetCompositionString()
{
	this->_toCompStr();
	return ((LPMYCOMPSTR)this->lpCompStr)->szCompStr;
}
CONST LPTSTR CompositionStringClass::GetResultString()
{
	return ((LPMYCOMPSTR)this->lpCompStr)->szResultStr;
}

TCHAR CompositionStringClass::GetPinYin() CONST
{
	LPUSRINPUT lpPtr;
	LPMYCOMPSTR lpMyComp = (LPMYCOMPSTR)this->lpCompStr;
	CHAR ret = NULL;
	if(lpMyComp->inputLen > 1)
	{
		lpPtr =  &(lpMyComp->input[lpMyComp->inputLen-1]);
		if(lpPtr->op_YIN)
			return lpPtr->YIN;
		--lpPtr;
		if(lpPtr->op_YIN)
			return lpPtr->YIN;
	}
	return ret;
}

UINT CompositionStringClass::GetStroke() CONST
{
	LPUSRINPUT lpPtr;
	LPMYCOMPSTR lpMyComp = (LPMYCOMPSTR)this->lpCompStr;
	if(lpMyComp->inputLen > 1)
	{
		lpPtr =  &(lpMyComp->input[lpMyComp->inputLen-1]);
		if(lpPtr->op_STROKE)
			return lpPtr->STROKE;
		--lpPtr;
		if(lpPtr->op_STROKE)
			return lpPtr->STROKE;
	}
	return 0;
}

USRINPUT CompositionStringClass::GetInput(UINT index) const
{
	LPMYCOMPSTR lpMyComp = (LPMYCOMPSTR)this->lpCompStr;
	if(index >= 0 && index < this->GetInputLen())
		return lpMyComp->input[index];
	throw "Index out of range in Class CompositionStringClass.";
}